package server;

import java.net.*;
import java.io.*;
import server.SQLDatabase;

import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;

public class SSLServer extends Thread {
	private ServerSocket serverSocket;
	private SQLDatabase jdb;

	public SSLServer(int port) throws IOException {

		jdb = new SQLDatabase();
		/** Connection Test */
		System.out.println("Connecting to SQL database...");
		if (jdb.openConnection("db53", "01831861")) {
			System.out.println("Connected to database");

		} else {
			System.out.println("Could not connect to database");
		}
		System.setProperty(
				"javax.net.ssl.keyStore",
				"/Users/davidlundberg/Documents/LTH/EIT060/Projekt/Certifikat/ServerKeyStore.jks");
		System.setProperty(
				"javax.net.ssl.trustStore",
				"/Users/davidlundberg/Documents/LTH/EIT060/Projekt/Certifikat/ServerTrustStore.ts");
		System.setProperty("javax.net.ssl.keyStorePassword", "ste11ar");
		System.setProperty("javax.net.ssl.trustStorePassword", "ste11ar");
		System.out.println("Server listening on port 3000.");

		SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory
				.getDefault();

		serverSocket = (SSLServerSocket) factory.createServerSocket(port);
		serverSocket.setSoTimeout(100000);
	}

	public void run() {
		boolean run = true;
		while (run) {
			while (true) {
				try {
					System.out.println("Waiting for client on port "
							+ serverSocket.getLocalPort() + "...");
					SSLSocket server = (SSLSocket) serverSocket.accept();
					System.out.println("Just connected to "
							+ server.getRemoteSocketAddress());

					DataInputStream in = new DataInputStream(
							server.getInputStream());
					DataOutputStream out = new DataOutputStream(
							server.getOutputStream());

					String username = null;
					String input;
					boolean loggedOn = false;
					int loginAttempts = 0;
					while (!loggedOn && loginAttempts < 5) {
						System.out.println("Waiting for client to login");
						username = in.readUTF().toString();
						if (jdb.clientExists(username)) {
							System.out.println("Client found");
						} else {
							System.out.println("Client not found");
						}
						input = in.readUTF().toString();
						if (jdb.tryLogin(username, input)) {
							out.writeUTF("correct");
							loggedOn = true;
							loginAttempts = 0;
						} else {
							loginAttempts++;
							if (loginAttempts == 5) {
								out.writeUTF("timeout");
								loginAttempts = 0;
							} else {
								out.writeUTF("incorrect");
							}
						}
					}
					boolean running = true;
					while (running) {
						System.out.println("Waiting for client...");
						input = in.readUTF().toString();
						if (input.equals("1")) {
							input = in.readUTF().toString();
							try {
								String journal = jdb
										.getJournal(input, username);
								out.writeUTF(journal);
								if (journal.equals("fel")) {
									System.out
											.println("Error when fetching journal");
								}
								System.out.println("Journal: " + journal
										+ " was fetched from database by: "
										+ username);
							} catch (Exception e) {
								out.writeUTF("fel ");
								run = true;
							}
						} else if (input.equals("2")) {
							input = in.readUTF().toString();
							int journalID = Integer.parseInt(input);
							input = in.readUTF().toString();
							if (jdb.modifyJournal(journalID, username, input)) {
								out.writeUTF("modified");
								System.out.println("Journal: " + journalID
										+ " was modified successfully");
							} else {
								out.writeUTF("modification failed");
								System.out.println("Journal: " + journalID
										+ " was not modified");
							}
						} else if (input.equals("3")) {
							String personNbr = in.readUTF().toString();
							String nurseNbr = in.readUTF().toString();
							String doctorNbr = in.readUTF().toString();
							int division = Integer.parseInt(in.readUTF()
									.toString());
							String data = in.readUTF().toString();
							if (jdb.insertJournal(personNbr, nurseNbr,
									doctorNbr, division, data, username)) {
								out.writeUTF("createdJournal");
								System.out.println("Journal created");
							} else {
								out.writeUTF("creation failed");
								System.out.println("Journal creation failed");
							}
						} else if (input.equals("4")) {
							input = in.readUTF().toString();
							if (jdb.deleteJournal(input, username)) {
								out.writeUTF("deleted");
								System.out.println("Journal :" + input
										+ " was deleted");
							} else {
								out.writeUTF("not deleted");
								System.out.println("User : " + username
										+ " was trying to delete journal: "
										+ input);
							}
							System.out.println("Waiting for client...");
							running = true;
						} else {
							out.writeUTF("quit");
							running = false;
						}
					}
					server.close();

				} catch (SocketTimeoutException s) {
					System.out.println("Socket timed out!");
					break;
				} catch (Exception e) {
					System.out.println("user logged off!");
					run = true;
				}
			}

		}
	}

	public static void main(String[] args) {
		try {
			Thread t = new SSLServer(3000);
			t.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}